package com.woniu.woniuYoga.comm.sentinel.exception;

import com.woniu.woniuYoga.comm.core.exception.*;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * @author: 付宽成
 * @description: 全局异常处理类，404、Feign、RestTemplate、一些自定义的异常进行单独处理，其他类型异常集中处理
 * @date: 2020/8/24 17:04
 * @version: 1.0
 */

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 链路调用中限流异常处理 (Feign)
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(FeignException.TooManyRequests.class)
    public ResponseEntity<ResultError> noHandlerExceptionHandler(FeignException.TooManyRequests e) {
        String message = e.getMessage();
        String resource = message.substring(message.indexOf("msg") + 7);
        resource = resource.substring(0, resource.indexOf("\""));
        ResultError resultError = ResultError.builder()
                .code(WoniuExceptionCode.SENTINEL_BLOCK.getCode())
                .msg(resource)
                .build();
        return new ResponseEntity<>(resultError, HttpStatus.TOO_MANY_REQUESTS);
    }

    /**
     * 链路调用中限流异常处理 (RestTemplate)
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(HttpClientErrorException.TooManyRequests.class)
    public ResponseEntity<ResultError> noHandlerExceptionHandler(HttpClientErrorException.TooManyRequests e) {
        String message = e.getMessage();
        String resource = message.substring(message.indexOf("msg") + 7);
        resource = resource.substring(0, resource.indexOf("\""));
        ResultError resultError = ResultError.builder()
                .code(WoniuExceptionCode.SENTINEL_BLOCK.getCode())
                .msg(resource)
                .build();
        return new ResponseEntity<>(resultError, HttpStatus.TOO_MANY_REQUESTS);
    }

    /**
     * 404 异常处理
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public ResponseEntity<ResultError> noHandlerFoundException(Exception e) {
        log.error("出现异常 code:{},message:{},class:{}", WoniuExceptionCode.SYS_URL_NOT_FOUNDED.getCode(),
                e.getMessage(), e.getClass().getName());
        ResultError resultError = ResultError.builder().code(404).msg("找不到资源" + e.getMessage()).build();
        return new ResponseEntity<>(resultError, HttpStatus.NOT_FOUND);
    }

    /**
     * 认证异常处理
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(WoniuAuthencticationException.class)
    public ResponseEntity<ResultError> authencticationException(WoniuAuthencticationException e) {
        WoniuException we = (WoniuException) e;
        log.error("出现异常 code:{},message:{},class:{}", we.getCode(),we.getMessage() ,we.getClass().getName());
        ResultError resultError = ResultError.errorExec(we);
        return new ResponseEntity<>(resultError, HttpStatus.UNAUTHORIZED);
    }

    /**
     * 未授权异常处理
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(WoniuUnauthencticationException.class)
    public ResponseEntity<ResultError> unauthencticationException(WoniuUnauthencticationException e) {
        WoniuException we = (WoniuException) e;
        log.error("出现异常 code:{},message:{},class:{}", we.getCode(),we.getMessage() ,we.getClass().getName());
        ResultError resultError = ResultError.errorExec(we);
        return new ResponseEntity<>(resultError, HttpStatus.FORBIDDEN);
    }

    /**
     * 自定义异常处理
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(WoniuException.class)
    public ResponseEntity<ResultError> woniuExceptionHandler(Exception e) {
        WoniuException we = (WoniuException) e;
        log.error("出现异常 code:{},message:{},class:{}", we.getCode(),we.getMessage() ,we.getClass().getName());
        ResultError resultError = ResultError.errorExec(we);
        return new ResponseEntity<>(resultError, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 其他异常统一处理
     *
     * @param e 异常类
     * @return 状态码 + 自定义封装的结果集对象
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ResultError> gloableExceptionHandler(Exception e) {
        log.error("出现异常 code:{},message:{},class:{}", WoniuExceptionCode.SYS_ERROR.getCode(),
                e.getMessage(), e.getClass().getName());
        ResultError resultError = ResultError.builder()
                .code(WoniuExceptionCode.SYS_ERROR.getCode())
                .msg(e.getMessage()).build();
        return new ResponseEntity<>(resultError, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
